using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Data;
using System.Collections;
using System.Collections.Specialized;
using System.Text;
using System.Reflection;
using System.Globalization;
using System.Xml;

namespace AresControls
{
	public class HGrid : Control, IPostBackDataHandler
	{
		private HControl[] m_HControls;
		private string m_Width="",m_DeleteAllMessage="",m_DeleteAllToolTip="",m_DeleteLineToolTip="",m_FormatedValue="",
			m_ReadOnlySourceColumn="",m_SortField="",m_PostBackSortString="",m_HomePageUrl="",m_InvokeOnChangeLine="",
			m_InvokeOnDeleteLine="",m_InvokeOnDeleteNewLine="",m_InvokeOnDeleteAllLines="",m_InvokeOnAddLine="",m_PathPrefix,
			m_InvokeOnAddNewLine="",m_InvokeOnRefreshGrid="",m_XmlFile="",m_Language="",m_RequiredString="",m_InvalidString="",m_AlertUnique="",
            m_HeaderRowForeColor = "#45FF5F", m_HeaderForeColor = "#45FF5F", m_HeaderRowBackgroundColor = "#3A6EA5", m_HeaderBackgroundColor = "#3A6EA5",
			m_Height = "300px",m_HeaderRowSelBackgroundColor = "#93B4D9";
		private bool m_DeleteAllLines = true,m_DeleteLine = true,m_ReadOnly = false,m_Paging = false,m_Searching = false,m_ShowFooter = true;
		private string[] m_DenyAutoIncrementOn = null,m_HeaderText,m_SetAllowNull;
		private bool[] m_SortColumns = null,m_SearchColumns = null,m_UniqueValueColumns = null;
		private int m_SessionKeysMaxNo = -1, m_MaxRowsCount = -1,m_PageSize = 20,m_HeaderFontSize = 8;
		public const String KEY_TEMP_GRID_VARS = "TempGridVars";

		public HGrid()
		{
		}

		public bool DeleteLine
		{
			get { return m_DeleteLine; }
			set { m_DeleteLine = value; }
		}

		public bool ShowFooter
		{
			get { return m_ShowFooter; }
			set { m_ShowFooter = value; }
		}


		public string InvokeOnAddLine
		{
			get { return m_InvokeOnAddLine; }
			set { m_InvokeOnAddLine = value; }
		}

		public string InvokeOnInsertBlankRow
		{
			get { return m_InvokeOnAddNewLine; }
			set { m_InvokeOnAddNewLine = value; }
		}

		public string InvokeOnRefreshGrid
		{
			get { return m_InvokeOnRefreshGrid; }
			set { m_InvokeOnRefreshGrid = value; }
		}

		public int MaxRowsCount
		{
			get { return m_MaxRowsCount; }
			set { m_MaxRowsCount = value; }
		}

		public bool ReadOnly
		{
			get { return m_ReadOnly; }
			set { m_ReadOnly = value; DeleteAllLines = !value; }
		}

		public string InvokeOnDeleteLine
		{
			get { return m_InvokeOnDeleteLine; }
			set { m_InvokeOnDeleteLine = value; }
		}

		public string InvokeOnDeleteNewLine
		{
			get { return m_InvokeOnDeleteNewLine; }
			set { m_InvokeOnDeleteNewLine = value; }
		}

		public string InvokeOnDeleteAllLines
		{
			get { return m_InvokeOnDeleteAllLines; }
			set { m_InvokeOnDeleteAllLines = value; }
		}

		public string InvokeOnChangeLine
		{
			get { return m_InvokeOnChangeLine; }
			set { m_InvokeOnChangeLine = value; }
		}

		public string HomePageUrl
		{
			get { return m_HomePageUrl; }
			set { m_HomePageUrl = value; }
		}

		public bool[] SortColumns
		{
			get { return m_SortColumns; }
			set { m_SortColumns = value; }
		}

		public bool[] SearchColumns
		{
			get { return m_SearchColumns; }
			set { m_SearchColumns = value; }
		}

		public bool[] UniqueValueColumns
		{
			get { return m_UniqueValueColumns; }
			set { m_UniqueValueColumns = value; }
		}

		public string SortField
		{
			get
			{
				return (Context.Session[UniqueID + "Sort"] != null)?(string)Context.Session[UniqueID + "Sort"]:m_SortField;
			}
			set
			{
				m_SortField = value;
				WriteGridVariableOnSession(UniqueID + "Sort", m_SortField);
			}
		}

		public string[] DenyAutoIncrementOn
		{
			get { return m_DenyAutoIncrementOn; }
			set { m_DenyAutoIncrementOn = value; }
		}

		public string[] SetAllowNull
		{
			get { return m_SetAllowNull; }
			set { m_SetAllowNull = value; }
		}

		public int SessionKeysMaxNo
		{
			get { return m_SessionKeysMaxNo; }
			set { m_SessionKeysMaxNo = value; }
		}

		public string DeleteLineToolTip
		{
			get { return m_DeleteLineToolTip; }
			set { m_DeleteLineToolTip = value; }
		}

		public string DeleteAllToolTip
		{
			get { return m_DeleteAllToolTip; }
			set { m_DeleteAllToolTip = value; }
		}

		public string DeleteAllMessage
		{
			get { return m_DeleteAllMessage; }
			set { m_DeleteAllMessage = value; }
		}

		public string ReadOnlySourceColumn
		{
			get { return m_ReadOnlySourceColumn; }
			set { m_ReadOnlySourceColumn = value; }
		}

		public string[] HeaderText
		{
			get { return m_HeaderText; }
			set { m_HeaderText = value; }
		}

		public bool DeleteAllLines
		{
			get { return m_DeleteAllLines; }
			set { m_DeleteAllLines = value; }
		}

		public HControl[] HControls
		{
			get { return m_HControls; }
			set { m_HControls = value; }
		}

		public string HeaderRowForeColor
		{
			get { return m_HeaderRowForeColor; }
			set { m_HeaderRowForeColor = value; }
		}

		public string HeaderForeColor
		{
			get { return m_HeaderForeColor; }
			set { m_HeaderForeColor = value; }
		}

		public string HeaderRowBackgroundColor
		{
			get { return m_HeaderRowBackgroundColor; }
			set { m_HeaderRowBackgroundColor = value; }
		}

		public string HeaderRowSelBackgroundColor
		{
			get { return m_HeaderRowSelBackgroundColor; }
			set { m_HeaderRowSelBackgroundColor = value; }
		}

		public string HeaderBackgroundColor
		{
			get { return m_HeaderBackgroundColor; }
			set { m_HeaderBackgroundColor = value; }
		}

		public string Width
		{
			get { return m_Width; }
			set { m_Width = value; }
		}

		public string Height
		{
			get { return m_Height; }
			set { m_Height = value; }
		}

		public string GetGridSourceGroup(string strGridName)
		{
			string strSourceGroup = strGridName;
			if (Context.Session[strGridName + "SourceGroup"] != null)
				strSourceGroup = (string)Context.Session[strGridName + "SourceGroup"];
			return strSourceGroup;
		}

		public DataSet GetGridDataSet(string strGridName)
		{
			string strSourceGroup = GetGridSourceGroup(strGridName);
			if (strSourceGroup == null || strSourceGroup == "")
				return null;
			else
				return ((DataSet)Context.Session[strSourceGroup]);
		}

		public DataView GetGridDataView(string strGridName)
		{
			object oTableIndex = Context.Session[strGridName + "TableIndex"];
			DataSet ds = GetGridDataSet(strGridName);
			if (oTableIndex == null || ds == null)
				return null;
			else
			{
				DataView dv = ds.Tables[(int)oTableIndex].DefaultView;
				dv.RowFilter = Context.Session[strGridName + "RowFilter"].ToString();
				dv.Sort = Context.Session[strGridName + "ViewSort"].ToString();
				return dv;
			}
		}

		public void DoSetGridSource(DataView dv, string strGridID)
		{
			if (dv != null)
			{
				WriteGridVariableOnSession(GetGridSourceGroup(strGridID), dv.Table.DataSet);
				WriteGridVariableOnSession(strGridID + "TableIndex", dv.Table.DataSet.Tables.IndexOf(dv.Table));
				WriteGridVariableOnSession(strGridID + "RowFilter", dv.RowFilter);
				WriteGridVariableOnSession(strGridID + "ViewSort", dv.Sort);
			}
			else
				WriteGridVariableOnSession(GetGridSourceGroup(strGridID), null);
		}

		public string SourceGroup
		{
			get
			{
				return GetGridSourceGroup(this.UniqueID);
			}
			set
			{
				WriteGridVariableOnSession(this.UniqueID + "SourceGroup", value);
			}
		}

		public DataView Source
		{
			get
			{
				return GetGridDataView(this.UniqueID);
			}
			set
			{
				if (value == null)
				{
					System.Web.SessionState.HttpSessionState tempSession = Context.Session.Contents;
					tempSession.Remove(UniqueID);
					Session_TempGridVars.Remove(UniqueID);
					tempSession.Remove(UniqueID + "DataFld");
					Session_TempGridVars.Remove(UniqueID + "DataFld");
					tempSession.Remove(UniqueID + "FillFunction");
					Session_TempGridVars.Remove(UniqueID + "FillFunction");
					tempSession.Remove(UniqueID + "ReadOnlyColumn");
					Session_TempGridVars.Remove(UniqueID + "ReadOnlyColumn");
					tempSession.Remove(UniqueID + "DenyOn");
					Session_TempGridVars.Remove(UniqueID + "DenyOn");
					tempSession.Remove(UniqueID + "Sort");
					Session_TempGridVars.Remove(UniqueID + "Sort");
					tempSession.Remove(UniqueID + "NrOfDecimals");
					Session_TempGridVars.Remove(UniqueID + "NrOfDecimals");
					tempSession.Remove(UniqueID + "DateFormats");
					Session_TempGridVars.Remove(UniqueID + "DateFormats");
					tempSession.Remove(UniqueID + "TableIndex");
					Session_TempGridVars.Remove(UniqueID + "TableIndex");
					tempSession.Remove(UniqueID + "SourceGroup");
					Session_TempGridVars.Remove(UniqueID + "SourceGroup");

					tempSession.Remove(UniqueID + "NewRowsArray");
					Session_TempGridVars.Remove(UniqueID + "NewRowsArray");

					SessionKeysMaxNo = (SessionKeysMaxNo == -1)?HControls.Length:-1;
					int i = 0;
					while (i<SessionKeysMaxNo && Context.Session[UniqueID + "Column" + i.ToString()] != null)
					{
						Context.Session.Remove(UniqueID + "Column" + i.ToString());
						Session_TempGridVars.Remove(UniqueID + "Column" + i++.ToString());
					}
				}
				else
				{
					DoSetGridSource(value, this.UniqueID);

					ArrayList a = BuildNewRowsArray(value);
					WriteGridVariableOnSession(this.UniqueID + "NewRowsArray", a);
				}
			}
		}

		private string[] GetTablePKs(DataView dv)
		{
			string[] arPKs = null;
			if (dv.Table.PrimaryKey.Length == 0)
			{
				if (dv.Table.Columns.Contains("ID"))
					arPKs = new string[]{"ID"};
			}
			else
			{
				arPKs = new string[dv.Table.PrimaryKey.Length];
				for (int i=0; i<dv.Table.PrimaryKey.Length; ++i)
					arPKs[i] = dv.Table.PrimaryKey[i].ColumnName;
			}
			return arPKs;
		}

		private ArrayList BuildNewRowsArray(DataView dv)
		{
			string[] arPKs = GetTablePKs(dv);
			if (arPKs == null)
				return null;

			ArrayList a = new ArrayList(dv.Count);
			for (int k=0; k<dv.Count; ++k)
			{
				string[] s = new string[arPKs.Length + 1];
				s[0] = k.ToString();
				for (int i=0; i<arPKs.Length; ++i)
					s[i+1] = dv[k][arPKs[i]].ToString();
				a.Add(s);
			}
			return a;
		}

		private string PostBackSortString
		{
			get { return m_PostBackSortString; }
			set { m_PostBackSortString = value; }
		}

		private string RequiredString
		{
			get { return m_RequiredString; }
			set { m_RequiredString = value; }
		}

		private string InvalidString
		{
			get { return m_InvalidString; }
			set { m_InvalidString = value; }
		}

		private string AlertUnique
		{
			get { return m_AlertUnique; }
			set { m_AlertUnique = value; }
		}

		private string PathPrefix
		{
			get { return m_PathPrefix; }
			set { m_PathPrefix = value; }
		}

		private ArrayList Session_TempGridVars
		{
			get
			{
				try
				{
					ArrayList retVal = (ArrayList)(Context.Session[KEY_TEMP_GRID_VARS]);
					if (retVal == null)
					{
						retVal = new System.Collections.ArrayList();
						Context.Session.Add(KEY_TEMP_GRID_VARS, retVal);
					}
					return retVal;
				}
				catch
				{
					return null;
				}
			}
			set
			{
				if (null == value)
				{
					Context.Session[KEY_TEMP_GRID_VARS] = null;
					Context.Session.Remove(KEY_TEMP_GRID_VARS);
				}
				else
				{
					ArrayList retVal = (ArrayList)(Context.Session[KEY_TEMP_GRID_VARS]);
					if (null == retVal)
						Context.Session.Add(KEY_TEMP_GRID_VARS, value);
					else
						Context.Session[KEY_TEMP_GRID_VARS] = value;
				}
			}
		}

		public bool Paging
		{
			get { return m_Paging; }
			set { m_Paging = value; }
		}

		public bool Searching
		{
			get { return m_Searching; }
			set { m_Searching = value; }
		}

		public int PageSize
		{
			get { return m_PageSize; }
			set { m_PageSize = value; }
		}

		public string XmlFile
		{
			get { return m_XmlFile; }
			set { m_XmlFile = value; }
		}

		public string Language
		{
			get { return m_Language; }
			set { m_Language = value; }
		}

		public int LineHeaderFontSize
		{
			get { return m_HeaderFontSize; }
			set { m_HeaderFontSize = value; }
		}

		public bool LoadPostData(String postDataKey, NameValueCollection values)
		{
			PostBackSortString = (string)values[UniqueID + "SortString"];
			return false;
		}

		public void RaisePostDataChangedEvent()
		{
		}

		public void GenerateGrid()
		{
			RequiredString = GetXMLValue("ALERT_REQUIRED_STRING");
			InvalidString = GetXMLValue("ALERT_INVALID_STRING");
			AlertUnique = GetXMLValue("ALERT_DUPLICATE");

			if (HControls == null || Source == null)
				return;

			Source = GetGridDataView(UniqueID);

			if (PostBackSortString != "" && PostBackSortString != m_SortField)
				m_SortField = SortField = Source.Sort = PostBackSortString;
			else
				if (m_SortField != "")
					Source.Sort = m_SortField;

			Source = Source;

			m_FormatedValue = GetOutputSource(GetGridDataView(UniqueID));
			PathPrefix = Context.Request.ApplicationPath;

			if (PathPrefix == "/")
				PathPrefix = "";

			string strOutput = "<div ondeactivate=\"GridBlur(\'" + UniqueID + "\');\" ";
			strOutput += (ReadOnly)?" GridReadOnly=\"true\" ":"";
			strOutput += (!DeleteLine)?" DeleteLine=\"false\" ":"";
			strOutput += (MaxRowsCount >= 0)?" MaxRowsCount=\"" + MaxRowsCount + "\" ":"";
			strOutput += (Paging)?" Paging=\"" + Paging + "\" PageSize=\"" + PageSize + "\" ":"";
			strOutput += " id=\"" + UniqueID + "BigSpan\" style=\"overflow:none;display:block\" >";
			Controls.Add(new LiteralControl(strOutput));

			strOutput = "<div id=\"" + UniqueID + "HeaderSpan\" style=\"width:" + Width + ";overflow-X:hidden;\">";
			Controls.Add(new LiteralControl(strOutput));

			Table t = new Table();
			t.ID = UniqueID + "Header";
			t.Attributes["style"] += ";background-Color:" + HeaderBackgroundColor + ";color:" + HeaderForeColor + ";";
			t.Font.Bold = true;
			t.Font.Size = 8;
			t.Font.Name = "Arial";
			t.BorderColor=System.Drawing.Color.Gray;
			t.BorderWidth=1;
			t.CellPadding=t.CellSpacing=0;
			t.GridLines=GridLines.Vertical;

			TableRow r = new TableRow();
			TableCell c = new TableCell();

			int tempInt = 35;
			strOutput = "<span GridId=\"" + UniqueID + "\" style=\"width:" + tempInt + "\">";
            strOutput += "<input type=\"image\" GridId=\"" + UniqueID + "\" alt=\"" + GetXMLValue("DELETE_ALL_TT") + "\" src=\"" + PathPrefix + "/Images/Ares/gr_del_all.jpg\" style=\"vertical-align:middle;width:35";
			strOutput += (!DeleteAllLines)?";visibility:hidden\" ":"\" onmouseover=\"style.cursor=\'hand\';\" onclick=\"event.returnValue=false;DeleteAllLines(this,\'" + GetXMLValue("DELETE_ALL_MSG") + "\');\"";
			strOutput += "/></span>";
			c.Controls.Add(new LiteralControl(strOutput));
			r.Cells.Add(c);

			string strSort = (m_SortField != "" && m_SortField.IndexOf(" ") > 0)?m_SortField.Substring(0,m_SortField.IndexOf(" ")):m_SortField;
			string strSortDir = (m_SortField != "" && m_SortField.IndexOf(" ") > 0)?m_SortField.Substring(m_SortField.IndexOf(" ") + 1):"";

			for (int j=0; j<HControls.Length; ++j)
			{
				c = new TableCell();
				c.HorizontalAlign = HorizontalAlign.Center;

				strOutput = "<span GridId=\"" + UniqueID + "\" ";

				strOutput += (UniqueValueColumns != null && UniqueValueColumns.Length == HControls.Length)?" UniqueValue='" + UniqueValueColumns[j].ToString().ToLower() + "' ":"";
				strOutput += (SortColumns != null && SortColumns.Length >= j && SortColumns[j] && HControls[j].DataSrc != "")?" onmouseover=\"style.cursor='hand';\" onclick=\"ClientSortGrid(this);\" ":"";
				tempInt = 0;
				strOutput += " style=\"width:" + (int.Parse(HControls[j].Width) + tempInt) + "\"> " + HeaderText[j];
				if (SortColumns != null && SortColumns.Length >= j && SortColumns[j] && HControls[j].DataSrc != "")
				{
					if (m_SortField != "" && strSort == HControls[j].DataSrc)
					{
                        strOutput += (strSortDir.ToLower() == "asc") ? "<input SortString=\"" + HControls[j].DataSrc + " desc\" onclick=\"event.returnValue=false;\" type=\"image\" GridId=\"" + UniqueID + "\" src=\"" + PathPrefix + "/Images/Ares/UpArrowButtonWhite.jpg\" style=\"position:relative;left:2px\" /><input SortString=\"" + HControls[j].DataSrc + " asc\" onclick=\"event.returnValue=false;\" type=\"image\" GridId=\"" + UniqueID + "\" src=\"" + PathPrefix + "/Images/Ares/DownArrowButtonWhite.jpg\" style=\"position:relative;left:2px;display:none\" />" : "<input SortString=\"" + HControls[j].DataSrc + " desc\" onclick=\"event.returnValue=false;\" type=\"image\" GridId=\"" + UniqueID + "\" src=\"" + PathPrefix + "/Images/Ares/UpArrowButtonWhite.jpg\" style=\"position:relative;left:2px;display:none\" /><input SortString=\"" + HControls[j].DataSrc + " asc\" onclick=\"event.returnValue=false;\" type=\"image\" GridId=\"" + UniqueID + "\" src=\"" + PathPrefix + "/Images/Ares/DownArrowButtonWhite.jpg\" style=\"position:relative;left:2px\" />";
					}
					else
					{
                        strOutput += "<input SortString=\"" + HControls[j].DataSrc + " asc\" onclick=\"event.returnValue=false;\" type=\"image\" GridId=\"" + UniqueID + "\" src=\"" + PathPrefix + "/Images/Ares/UpArrowButtonWhite.jpg\" style=\"position:relative;left:2px;display:none\" /><input SortString=\"" + HControls[j].DataSrc + " desc\" onclick=\"event.returnValue=false;\" type=\"image\" GridId=\"" + UniqueID + "\" src=\"" + PathPrefix + "/Images/Ares/DownArrowButtonWhite.jpg\" style=\"position:relative;left:2px;display:none\" />";
					}
				}
				strOutput += "</span>";
				c.Controls.Add(new LiteralControl(strOutput));
				r.Cells.Add(c);
				c.Attributes["style"] += (HeaderText[j] == "")?";border:0;":"";
			}
			r.Cells.AddAt(0,c);
			t.Rows.Add(r);
			Controls.Add(t);

			strOutput = "</div>";
			Controls.Add(new LiteralControl(strOutput));

			strOutput = "<div oncontextmenu=\"HGridCM();\" onactivate=\"HGridActivate();\" onscroll=\"HGridScroll(this);\" SpanWidth=\"" + Width + "\" SpanHeight=\"" + Height + "\" ScrolledX=\"\" ScrolledY=\"\" id=\"SpanContentGrid" + UniqueID + "\" style=\"overflow-Y:auto;position:relative;top:-1;width:" + Width + ";height:" + Height + "\" >";
			Controls.Add(new LiteralControl(strOutput));

			t = new Table();
			t.BackColor = System.Drawing.Color.White;
			t.ID = UniqueID + "ContentGrid";
			t.BorderColor = System.Drawing.Color.Gray;
			t.BorderWidth=1;
			t.CellPadding=t.CellSpacing=0;
			t.GridLines=GridLines.Both;

			r = new TableRow();
			c = new TableCell();
			c.Attributes["style"] += "background-color:" + HeaderRowBackgroundColor;
			strOutput = "<input LineAdded=\"true\" GridId=\"" + UniqueID + "\" ReadOnlyLine=\"false\" tabindex=\"-1\" readonly type=\"text\" style=\"width:25;height:18px;font-size:" + LineHeaderFontSize + "pt;font-weight:bold;margin:0;border:0;color:" + HeaderRowForeColor + ";text-align:center;background-color:" + HeaderRowBackgroundColor + ";font-family:Arial\" />";
            strOutput += "<input tabindex=-1 type=\"image\" GridId=\"" + UniqueID + "\" alt=\"" + GetXMLValue("DELETE_LINE_TT") + "\" src=\"" + PathPrefix + "/Images/Ares/gr_del_line.jpg\" style=\"vertical-align:middle;width:10;height:18;background-color:" + HeaderRowBackgroundColor + "\" onmouseover=\"style.cursor=\'hand\';\" onclick=\"event.returnValue=false;DeleteLine(this);\" />";
			c.Controls.Add(new LiteralControl(strOutput));
			r.Cells.Add(c);

			for (int j=0; j<HControls.Length; ++j)
			{
				c = new TableCell();
				HControl HC = HControls[j];
				HC.GridControl = true;
				c.Attributes["style"] += (HC.ReadOnly)?";background-color:#DEDEDE":";background-color:#FFFFFF";
				HC.GridId = UniqueID;
				if (HC.DataSrc != "")
					HC.Required = !Source.Table.Columns[HC.DataSrc].AllowDBNull;
				switch (HControls[j].GetType().Name)
				{
					case "HInput" :
						HInput HI = (HInput)HControls[j];
						if (HI.DataSrc != "")
						{
							HI.NumericFieldType = Source.Table.Columns[HI.DataSrc].DataType.Name;
							HI.MaxLength = (Source.Table.Columns[HI.DataSrc].DataType.Name == "String" && Source.Table.Columns[HI.DataSrc].MaxLength > 0)?Source.Table.Columns[HI.DataSrc].MaxLength:HI.MaxLength;
							HI.DefaultValue = (Source.Table.Columns[HI.DataSrc].DefaultValue != System.DBNull.Value)?(Source.Table.Columns[HI.DataSrc].DataType.Name == "Decimal" &&	HI.NrOfDecimals >= 0)?Decimal.Parse(Source.Table.Columns[HI.DataSrc].DefaultValue.ToString()).ToString("f" + HI.NrOfDecimals):Source.Table.Columns[HI.DataSrc].DefaultValue.ToString():HI.DefaultValue;
						}
						HI.AlertInvalidString = InvalidString;
						HI.AlertRequiredString = (HI.Required)?RequiredString:"";
						break;
					case "HCheckBox" :
						HCheckBox HChk = (HCheckBox)HControls[j];
						HChk.DefaultValue = (HChk.DataSrc != "" && Source.Table.Columns[HChk.DataSrc].DefaultValue != System.DBNull.Value)?(bool)Source.Table.Columns[HChk.DataSrc].DefaultValue:HChk.DefaultValue;
						c.HorizontalAlign = HorizontalAlign.Center;
						break;
					case "HSelect" :
						HSelect HSel = (HSelect)HControls[j];
						if (HSel.DataSrc != "" && Source.Table.Columns[HSel.DataSrc].DefaultValue != System.DBNull.Value)
							HSel.DefaultValue = Source.Table.Columns[HSel.DataSrc].DefaultValue.ToString();
						HSel.CellIndex = j;
						HSel.AlertRequiredString = (HSel.Required)?RequiredString:"";
						break;
					case "HSelection" :
						HSelection HS = (HSelection)HControls[j];
						if (HS.DataSrc != "" && Source.Table.Columns[HS.DataSrc].DefaultValue != System.DBNull.Value)
							HS.DefaultValue = Source.Table.Columns[HS.DataSrc].DefaultValue.ToString();
						HS.AlertInvalidString = InvalidString;
						HS.AlertRequiredString = (HS.Required)?RequiredString:"";
						break;
					case "HDate" :
						HDate HD = (HDate)HControls[j];
						HD.Value = "";
						if (HD.DataSrc != "" && Source.Table.Columns[HD.DataSrc].DefaultValue != System.DBNull.Value)
							HD.DefaultValue = Source.Table.Columns[HD.DataSrc].DefaultValue.ToString();
						HD.AlertRequiredString = (HD.Required)?RequiredString:"";
						break;
				}
				c.Controls.Add(HC);
				r.Cells.Add(c);
			}

			t.Rows.Add(r);
			Controls.Add(t);
			strOutput = "</div>";

			if (Paging || Searching)
			{
				strOutput += (Paging)?"<div id=" + UniqueID + "Paging PageSize=\"" + PageSize + "\" PageIndex=\"0\" >":"<div >";
				strOutput += "<table cellpading=0 cellspacing=0><tr>";
				if (Paging)
				{
                    strOutput += "<td><input alt=\"" + GetXMLValue("FIRST_PAGE") + "\" GridId=\"" + UniqueID + "\" onclick=\"OnFirstPage(\'" + UniqueID + "\');\" tabIndex=-1 type=\"image\" style=\"height:16px;width:18px\" GridId=\"" + UniqueID + "\" src=\"" + PathPrefix + "/Images/Ares/first_white.jpg" + "\" /></td><td>";
                    strOutput += "<input alt=\"" + GetXMLValue("PREV_PAGE") + "\" GridId=\"" + UniqueID + "\" onclick=\"OnPreviousPage(\'" + UniqueID + "\');\" tabIndex=-1 type=\"image\" style=\"height:16px;width:18px\" GridId=\"" + UniqueID + "\" src=\"" + PathPrefix + "/Images/Ares/left_white.jpg" + "\" /></td><td nowrap>";
					strOutput += "<span GridId=\"" + UniqueID + "\" style=\"padding:2;height:16;font-size:7pt;font-family:Arial;margin:0;border-width:0;color:#442200;background-color:#FFFFFF\">pag.</span>";
					strOutput += "<input GridId=\"" + UniqueID + "\" onbeforedeactivate=\"OnPageInputBeforeDeactivate(this);\" onkeydown=\"OnPageInputKeyDown(this, event.keyCode);\" id=" + UniqueID + "CPageNo type=\"text\" style=\"padding:2;height:16;font-size:7pt;font-family:Arial;margin:0;border:1px solid #3A6EA5;color:#442200;text-align:right;background-color:#FFFFFF;width:20px\"/></td><td nowrap>";
					strOutput += "<span GridId=\"" + UniqueID + "\" style=\"padding:2;height:16;font-size:7pt;font-family:Arial;margin:0;border-width:0;color:#442200;background-color:#FFFFFF\">/</span>";
					strOutput += "<span id=" + UniqueID + "MPageNo GridId=\"" + UniqueID + "\" style=\"padding:2;height:16;font-size:7pt;font-family:Arial;margin:0;border-width:0;color:#442200;background-color:#FFFFFF\">";
					strOutput += (Source.Count%PageSize).ToString();
					strOutput += "</span></td><td>";
                    strOutput += "<input alt=\"" + GetXMLValue("NEXT_PAGE") + "\" GridId=\"" + UniqueID + "\" onclick=\"OnNextPage(\'" + UniqueID + "\');\" tabIndex=-1 type=\"image\" style=\"height:16px;width:18px\" GridId=\"" + UniqueID + "\" src=\"" + PathPrefix + "/Images/Ares/right_white.jpg" + "\" /></td><td>";
                    strOutput += "<input alt=\"" + GetXMLValue("LAST_PAGE") + "\" GridId=\"" + UniqueID + "\" onclick=\"OnLastPage(\'" + UniqueID + "\');\" tabIndex=-1 type=\"image\" style=\"height:16px;width:18px\" GridId=\"" + UniqueID + "\" src=\"" + PathPrefix + "/Images/Ares/last_white.jpg" + "\" /></td><td>";
					strOutput += "<input GridId=\"" + UniqueID + "\" onbeforedeactivate=\"OnPageSizeInputBeforeDeactivate(this);\" onkeydown=\"OnPageSizeInputKeyDown(this, event.keyCode);\" id=" + UniqueID + "CPageSize type=\"text\" style=\"padding:2;height:16;font-size:7pt;font-family:Arial;margin:0;border:1px solid #3A6EA5;color:#442200;text-align:right;background-color:#FFFFFF;width:20px\"/></td><td nowrap>";
					strOutput += "<span GridId=\"" + UniqueID + "\" style=\"padding:2;height:16;font-size:7pt;font-family:Arial;margin:0;border-width:0;color:#442200;background-color:#FFFFFF\">";
					strOutput += "/ pag.</span></td>";
				}
				if (Searching)
				{
					strOutput += "<td><input AlertInvalidString=\"" + InvalidString + "\" GridId=\"" + UniqueID + "\" onkeydown=\"OnFilterGridInputKeyDown(this, event.keyCode, new Array(" + BuildArray(GetGridColumns(HControls)) + "), new Array(" + BuildArray(SearchColumns) + "));\" id=" + UniqueID + "FilterGrid type=\"text\" style=\"padding:2;height:16;font-size:7pt;font-family:Arial;margin:0;border:1px solid #3A6EA5;color:#442200;text-align:right;background-color:#FFFFFF;width:100px\"/>";
					strOutput += "</td><td>";
                    strOutput += "<input alt=\"" + GetXMLValue("SEARCH") + "\" GridId=\"" + UniqueID + "\" onclick=\"OnFilterGrid(this, new Array(" + BuildArray(GetGridColumns(HControls)) + "), new Array(" + BuildArray(SearchColumns) + "));\" tabIndex=-1 type=\"image\" style=\"height:16px;width:18px\" GridId=\"" + UniqueID + "\" src=\"" + PathPrefix + "/Images/Ares/search.jpg" + "\" />";
					strOutput += "</td>";
				}
				strOutput += "</tr></table>";
				strOutput += "</div>";
			}

			strOutput += "<input type=\"hidden\" value=\"unchanged\" index=\"\" name=" + UniqueID + "ChangeFlag  />";
			strOutput += "<input type=\"hidden\" value=\"" + PostBackSortString + "\" name=" + UniqueID + "SortString  />";
			strOutput += "<input type=\"hidden\" value=\"" + m_FormatedValue + "\" name=" + UniqueID + " />";
			strOutput += "<input type=\"hidden\" value=\"" + HomePageUrl + "\" name=" + UniqueID + "HomePageUrl />";
			strOutput += "<input type=\"hidden\" value=\"" + Source.RowFilter + "\" name=" + UniqueID + "FilterString />";
			strOutput += "<input type=\"hidden\" value=\"" + AlertUnique + "\" name=" + UniqueID + "AlertUnique />";
			strOutput += "<input type=\"hidden\" value=\"" + ShowFooter + "\" name=" + UniqueID + "ShowFooter />";

			strOutput += (InvokeOnChangeLine != "")?"<input type=\"hidden\" value=\"" + InvokeOnChangeLine + "\" name=" + UniqueID + "InvokeOnChangeLine />":"";
			strOutput += (InvokeOnDeleteLine != "")?"<input type=\"hidden\" value=\"" + InvokeOnDeleteLine + "\" name=" + UniqueID + "InvokeOnDeleteLine />":"";
			strOutput += (InvokeOnDeleteNewLine != "")?"<input type=\"hidden\" value=\"" + InvokeOnDeleteNewLine + "\" name=" + UniqueID + "InvokeOnDeleteNewLine />":"";
			strOutput += (InvokeOnDeleteAllLines != "")?"<input type=\"hidden\" value=\"" + InvokeOnDeleteAllLines + "\" name=" + UniqueID + "InvokeOnDeleteAllLines />":"";
			strOutput += (InvokeOnAddLine != "")?"<input type=\"hidden\" value=\"" + InvokeOnAddLine + "\" name=" + UniqueID + "InvokeOnAddLine />":"";
			strOutput += (InvokeOnInsertBlankRow != "")?"<input type=\"hidden\" value=\"" + InvokeOnInsertBlankRow + "\" name=" + UniqueID + "InvokeOnAddNewLine />":"";
			strOutput += (InvokeOnRefreshGrid != "")?"<input type=\"hidden\" value=\"" + InvokeOnRefreshGrid + "\" name=" + UniqueID + "InvokeOnRefreshGrid />":"";

			strOutput += "<input type=\"hidden\" value=\"" + HeaderRowBackgroundColor + "\" name=" + UniqueID + "HRBGColor />";
			strOutput += "<input type=\"hidden\" value=\"" + HeaderRowSelBackgroundColor + "\" name=" + UniqueID + "HRSBGColor />";

			strOutput += "<input type=\"hidden\" value=\"" + GetOutputRO(GetGridDataView(UniqueID)) + "\" name=" + UniqueID + "ReadOnlyLines />";
			strOutput += "<input type=\"hidden\" value=\"new Array(" + BuildArray(GetGridColumns(HControls)) + ")\" name=\"" + UniqueID + "ColumnNames\" />";

			strOutput += "</div>";

			WriteGridVariableOnSession(UniqueID + "DataFld", GetGridColumns(HControls));
			WriteGridVariableOnSession(UniqueID + "FillFunction", GetFillFunctionArray(HControls));
			WriteGridVariableOnSession(UniqueID + "ReadOnlyColumn", ReadOnlySourceColumn);

			int[] nDecimalsNo = new int[HControls.Length];
			for (int i=0; i<HControls.Length; ++i)
				if (HControls[i].DataSrc !="")
					if (HControls[i].GetType().Name == "HInput")
						nDecimalsNo[i] = ((HInput)HControls[i]).NrOfDecimals;
			WriteGridVariableOnSession(UniqueID + "NrOfDecimals", nDecimalsNo);

			string[] strDateFormats = new string[HControls.Length];
			for (int i=0; i<HControls.Length; ++i)
				if (HControls[i].DataSrc !="")
					if (HControls[i].GetType().Name == "HDate")
						strDateFormats[i] = ((HDate)HControls[i]).Pattern;
			WriteGridVariableOnSession(UniqueID + "DateFormats", strDateFormats);

			if (SetAllowNull != null)
			{
				int i = 0;
				while (i<SetAllowNull.Length && !Source.Table.Columns[SetAllowNull[i]].AllowDBNull)
					Source.Table.Columns[SetAllowNull[i++]].AllowDBNull = true;
//				WriteGridVariableOnSession(UniqueID, Source);
				DoSetGridSource(this.Source, this.UniqueID);
			}
			WriteGridVariableOnSession(UniqueID + "DenyOn", DenyAutoIncrementOn);
			Controls.Add(new LiteralControl(strOutput));
		}

		private string GetOutputSource(DataView dView)
		{
			StringBuilder resultString = new StringBuilder("");

			DataRowView dRowView;
			string[] strNativeTypes, strGridTypes;
			strNativeTypes = strGridTypes = null;
			int[] nDecimalsNo = null;

			if (dView.Count > 0)
			{
				strNativeTypes = strGridTypes = new string[HControls.Length];
				nDecimalsNo = new int[HControls.Length];
				int i = 0;
				while (i<HControls.Length && HControls[i].DataSrc !="")
				{
					strNativeTypes[i] = dView.Table.Columns[HControls[i].DataSrc].DataType.Name;
					strGridTypes[i] = HControls[i].GetType().Name;
					nDecimalsNo[i] = (strGridTypes[i] == "HInput")?((HInput)HControls[i++]).NrOfDecimals:nDecimalsNo[i++];
				}
			}

			for (int i=0; i<dView.Count; ++i)
			{
				dRowView = dView[i];
				for (int j=0; j<HControls.Length; ++j)
				{
					if (HControls[j].DataSrc != "")
					{
						string strValue = "";
						if (dRowView.Row.Table.Columns[HControls[j].DataSrc].DataType.FullName != "System.DateTime")
							strValue = dRowView[HControls[j].DataSrc].ToString();
						else
						{
							if (dRowView[HControls[j].DataSrc] != System.DBNull.Value)
							{
								if (((HDate)HControls[j]).Pattern == HDate.PATTERN_DD_MM_YYYY_hh_mm_ss || 
									((HDate)HControls[j]).Pattern == HDate.PATTERN_MM_DD_YYYY_hh_mm_ss)
									strValue = ((DateTime)dRowView[HControls[j].DataSrc]).ToString("G", DateTimeFormatInfo.InvariantInfo);
								else
									strValue = ((DateTime)dRowView[HControls[j].DataSrc]).ToString("d", DateTimeFormatInfo.InvariantInfo);
							}
						}

						resultString = (strValue != "" && strNativeTypes[j] == "Decimal" && strGridTypes[j] == "HInput" && nDecimalsNo[j] >= 0)?resultString.Append(new StringBuilder(Decimal.Parse(strValue).ToString("f" + nDecimalsNo[j]))):resultString.Append(new StringBuilder(strValue.Replace("\"","&quot;").Replace("<","&lt;").Replace(">","&gt;")));
					}
					else
					{
						if (HControls[j].FillFunction != null)
						{
							MethodInfo FillFunction = null;
							try
							{
								FillFunction = (HControls[j].FillFunction[0].GetType()).GetMethod(HControls[j].FillFunction[1].ToString());
							}
							catch{}

							resultString.Append((FillFunction != null)?FillFunction.Invoke(HControls[j].FillFunction[0], new object[]{dRowView.DataView,i, j}).ToString().Replace("\"", "&quot;").Replace("<","&lt;").Replace(">","&gt;"):"");
						}
						else
							resultString.Append("");
					}
					if (j < HControls.Length-1)
						resultString.Append(new StringBuilder(((char)3).ToString() + ((char)4).ToString()));
				}
				if (i < dView.Count-1)
					resultString.Append(new StringBuilder(((char)2).ToString() + ((char)4).ToString()));
			}

			return resultString.ToString();
		}

		private string GetOutputRO(DataView dView)
		{
			if (ReadOnlySourceColumn == "")
				return "";
			string resultString = "";
			DataRowView dRowView = null;
			int i=0;
			while (i<dView.Count)
			{
				dRowView = dView[i];
				resultString += dRowView[ReadOnlySourceColumn].ToString();
				if (i < dView.Count-1)
					resultString += "#";
				i++;
			}
			return resultString;
		}

		private ArrayList GetGridColumns(HControl[] hControls)
		{
			ArrayList arrResult = new ArrayList(hControls.Length);
			int i = 0;
			while (i<hControls.Length)
				arrResult.Add(hControls[i++].DataSrc);

			return arrResult;
		}

		private ArrayList GetFillFunctionArray(HControl[] hControls)
		{
			ArrayList arrResult = new ArrayList(hControls.Length);
			int i = 0;
			while (i<hControls.Length)
				arrResult.Add(hControls[i++].FillFunction);

			return arrResult;
		}

		private string BuildArray(string[] ar)
		{
			string s = "";
			for (int i=0; i<ar.Length; ++i)
				s += "'" + ar[i].ToString() + "', ";
			s = (s.Length > 0) ? s.Substring(0, s.Length - 2) : s;
			return s;
		}

		private string BuildArray(ArrayList ar)
		{
			string s = "";
			for (int i=0; i<ar.Count; ++i)
				s += "'" + ar[i].ToString() + "', ";
			s = (s.Length > 0) ? s.Substring(0, s.Length - 2) : s;
			return s;
		}

		private string BuildArray(bool[] ar)
		{
			string s = "";
			for (int i=0; i<ar.Length; ++i)
				s += "'" + ar[i].ToString() + "', ";
			s = (s.Length > 0) ? s.Substring(0, s.Length - 2) : s;
			return s;
		}

		private XmlElement GetXMLFile()
		{
			string strXMLPath = Page.Server.MapPath(XmlFile);
			XmlTextReader m_XReader = new XmlTextReader(strXMLPath);
			XmlDocument xmlObj = new XmlDocument();
			xmlObj.Load(m_XReader);

			return xmlObj.DocumentElement;
		}

		private string GetXMLValue(string strTagName)
		{
			try
			{
				return GetXMLFile().GetElementsByTagName(strTagName).Item(0).Attributes.GetNamedItem(Language).Value;
			}
			catch (Exception)
			{
				return "???";
			}
		}

		private void WriteGridVariableOnSession(string strTagName, object objSes)
		{
			Context.Session[strTagName] = objSes;
			for (int i=0; i<Session_TempGridVars.Count; ++i)
				if (Session_TempGridVars[i].ToString() == strTagName)
					return;

			Session_TempGridVars.Add(strTagName);
		}
	}
}
